package com.hmall.spring;

import com.hmall.annotation.RpcScan;
import com.hmall.annotation.RpcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.stereotype.Component;

@Slf4j
public class CustomScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {

    private ResourceLoader resourceLoader;
    private static final String SPRING_BEAN_BASE_PACKAGE = "com.hmall";
    private static final String BASE_PACKAGE_ATTRIBUTE_NAME = "basePackages";

    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(RpcScan.class.getName()));//AnnotationAttributes本质为增强版MAP集合，fromMap将普通MAP包装为AnnotationAttributes
        String[] rpcScanBasePackage = new String[0];
        if (annotationAttributes != null) {
            rpcScanBasePackage = annotationAttributes.getStringArray(BASE_PACKAGE_ATTRIBUTE_NAME);//获取basePackage的value
        }
        if (rpcScanBasePackage.length == 0) {
            rpcScanBasePackage = new String[] {((StandardAnnotationMetadata) annotationMetadata).getClass().getPackage().getName()};//获取要扫描的路径
        }
        CustomScanner rpcServiceScanner = new CustomScanner(beanDefinitionRegistry, RpcService.class);
        CustomScanner springBeanScanner = new CustomScanner(beanDefinitionRegistry, Component.class);
        if (resourceLoader != null) {
            rpcServiceScanner.setResourceLoader(resourceLoader);
            springBeanScanner.setResourceLoader(resourceLoader);
        }
        int rpcServiceCount = rpcServiceScanner.scan(rpcScanBasePackage);//将@RpcScan中指定路径下的带有@RpcService注解的类注册到IOC容器
        log.info("rpcServiceScanner扫描的数量 [{}]", rpcServiceCount);
        int springBeanAmount = springBeanScanner.scan(SPRING_BEAN_BASE_PACKAGE);//将github.javaguide路径下的带有@Component注解的类注册到IOC容器
        log.info("springBeanScanner扫描的数量 [{}]", springBeanAmount);
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}
